//
//  DKModel.h
//  ZhangAo
//
//  Created by 张奥 on 15/4/15.
//  Copyright (c) 2015年 DKHS. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "DKModelKeyMapProtocol.h"

@interface NSDictionary (DKModel)

- (void)toModel:(id)model;

@end

/**
 *  enableKeyMapManager 默认为 YES，将会使用 DKKeyMapManager 作 key 的映射
 */
@interface DKModel : NSObject <DKModelKeyMapProtocol>

/**
 *  根据Dictionary或Array实例化成Model
 *
 *  @param data dictionary或array
 *
 *  @return 对象
 */
- (id)initWithData:(id)data;

/**
 *  Copy 某个 Model 的属性到 self 
 */
- (void)copyModelValueWithSourceModel:(DKModel *)sourceModel;

/**
 *  Copy 某个 Dict 的值到 self
 */
- (void)copyModelValueWithSourceDict:(NSDictionary *)sourceDict;

/**
 *  如果是用一个字典初始化Model，则data总是返回nil，
 *  如果是用一个数组初始化Model，则会返回映射后的Model的集合。
 */
@property (nonatomic, readonly) NSArray *data;

@property (nonatomic, strong) id bodyData;

/**
 *  默认为 YES，表示该 Model 支持从 bodyData 映射
 */
- (BOOL)hasProperties;

/**
 *  Model to Dictionary
 */
- (NSDictionary *)toDictionary;

/**
 *  返回当前属性下所包含的对象的类型
 *  如果当前对象下的属性有包含NSArray数组类型需要被反序列成对象，则重写当前方法
 *  @param propertyName 属性名称
 *
 *  @return 属性所包含的对象类型***********
 */
- (Class)classAtInsideOfObjectWithProperty:(NSString *)propertyName;

/**
 *  在映射成字典时，会忽略指定的属性名，如@[@"userInfo"]
 *
 *  @param objects    包含需要忽略的属性名的数组
 */
- (void)addIgnoredObjects:(NSArray *)objects;

/**
 *  需要手动映射的对象，支持多个映射
 *  如 @{@"id" : @"productId" , @"description" : @"summary"} 将会把id、description的key值映射到model的productId、summary属性上
 *
 *  @param dict 映射的字典
 */
- (void)addManualMappingDict:(NSDictionary *)dict;

// subclass hook methods

/**
 *  会在将数据转成Model时调用
 *
 *  @param key   将要映射的key
 *  @param value 将要映射的value
 *
 *  @return 是否需要映射，默认总是返回YES
 */
- (BOOL)shouldToModelMappingKey:(NSString *)key forValue:(id)value;

/**
 *  会在将Model映射成字典时调用
 *
 *  @param key   将要映射的key
 *  @param value 将要映射的value
 *
 *  @return 默认将 key 和 value 打包成字典后返回
 */
- (NSDictionary *)shouldToDictionaryMappingKey:(NSString *)key forValue:(id)value;

+ (void)setGlobalObjectToDateBlock:(NSDate *(^)(id object, DKModel *model))block;

+ (void)setGlobalDateToObjectBlock:(id (^)(NSDate *date, DKModel *model))block;

@end
